package ch.ethz.fcl.metrobuzz.data.loader.MRTUncertain;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;

import ch.ethz.fcl.metrobuzz.algorithm.network.Path;
import ch.ethz.fcl.metrobuzz.algorithm.network.all_simple_paths.AllSimplePaths;
import ch.ethz.fcl.metrobuzz.data.MBData;
import ch.ethz.fcl.metrobuzz.data.loader.PublicTransitType;
import ch.ethz.fcl.metrobuzz.data.scene.basemap.Node;
import ch.ethz.fcl.metrobuzz.data.transit.Stop;
import ch.ethz.fcl.metrobuzz.data.transit.TransitLine;

/**
 * assigning a probability for each of the RTS route
 * 
 * @author Zeng Wei
 * @email zeng@arch.ethz.ch
 * 
 */

public class MRTUncertaintyProcessor {
	private int tripsLimit = 1000000;

	FileWriter fw = null;
	BufferedWriter bw = null;
	int sampledTrips = 0;

	@SuppressWarnings("resource")
	public void load(MBData data, String filePath) {
		int numOfTrips = 0;
		try {
			BufferedReader reader = new BufferedReader(new FileReader(filePath));
			reader.readLine();// first line is skipped
			String tripEntry = null;

			File file = new File("res/Singapore/sampled_raw_data_MRTUncertain");

			// if file doesn't exists, then create it
			if (!file.exists()) {
				file.createNewFile();
			}

			fw = new FileWriter(file.getAbsoluteFile());
			bw = new BufferedWriter(fw);

			while ((tripEntry = reader.readLine()) != null
					&& numOfTrips < tripsLimit) {
				inputProcess(data, tripEntry);
				numOfTrips++;
			}

			bw.flush();
			bw.close();

			fw.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("Total " + numOfTrips + " trip entries loaded");
	}

	private void inputProcess(MBData data, String input) throws Exception {
		String[] fields = input.split(",");

		if (fields.length != 15) {
			throw new Exception("Wrong input fields");
		}

		Stop boardStop, alightStop;
		PublicTransitType type;
		if (fields[3].equals("RTS"))
			type = PublicTransitType.RTS;
		else if (fields[3].equals("Bus"))
			type = PublicTransitType.BUS;
		else {
			throw new Exception("Unknown trip type");
		}

		String boardStopName = fields[7].replace("STN ", "");
		String alightStopName = fields[8].replace("STN ", "");

		if (boardStopName.endsWith(alightStopName))
			return;

		if (type == PublicTransitType.BUS) {
			// field 4 is transit line number, 5 is direction (0/1), 6 is
			// registration number
			TransitLine transit = data.getPublicTransit().getLine(
					fields[4].trim());

			if (transit == null)
				return;

			if (boardStopName.length() < 5)
				boardStopName = "0" + boardStopName;
			if (alightStopName.length() < 5)
				alightStopName = "0" + alightStopName;
			boardStop = data.getPublicTransit().getStopByStopId(boardStopName);
			alightStop = data.getPublicTransit()
					.getStopByStopId(alightStopName);

			if (boardStop == null)
				return;

			if (alightStop == null)
				return;

			if (transit != null) {
				bw.write(input + "\n");
				sampledTrips++;

			}
		} else if (type == PublicTransitType.RTS) { // if it is MRT lines
			boardStop = data.getPublicTransit()
					.getStopByStopName(boardStopName);
			alightStop = data.getPublicTransit().getStopByStopName(
					alightStopName);

			Node sourceNode = data.getScene().getNode(boardStop.getId());
			Node endNode = data.getScene().getNode(alightStop.getId());

			List<Path> paths = AllSimplePaths.getAllSimplePaths(data,
					sourceNode, endNode);
			List<Float> possibilities = AllSimplePaths.pathPossibility(paths);

			for (int i = 0; i < paths.size(); i++) {
				for (int k = 0; k < fields.length - 1; k++) {
					if (k == 7) // boarding station
						bw.write(paths.get(i).toString() + ",");
					else if (k == 8) // alighting station
						bw.write(possibilities.get(i) + ",");
					else
						bw.write(fields[k] + ",");
				}

				bw.write(fields[fields.length - 1] + "\n");
				sampledTrips++;
			}
		}
	}

}
